home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / TURB_VIS / TVDMX / README.DOC < prev    next >
Text File  |  1994-06-20  |  51KB  |  1,301 lines

  1.  
  2.   tvDMX  (c) 1992,94 Randolph Beck
  3.   =====
  4.  
  5.                   ░░░░░   ░░     ░░ ░░   ░░
  6.      ░░            ░░ ░░  ░░░   ░░░  ░░ ░░
  7.     ░░░░░ ░░   ░░  ░░  ░░ ░░░░ ░░░░   ░░░
  8.      ░░    ░░ ░░   ░░  ░░ ░░ ░░░ ░░   ░░░
  9.      ░░     ░░░    ░░  ░░ ░░  ░  ░░  ░░ ░░
  10.       ░░     ░    ░░░░░░  ░░     ░░ ░░   ░░
  11.  
  12.  
  13.   tvDMX is an object-oriented data entry platform for Turbo Vision with
  14.         a mechanism to create scrolling forms, spreadsheets and tables.
  15.  
  16.  
  17.  
  18.   REGISTRATION AND LICENSING
  19.   ==========================
  20.  
  21.   This is a shareware product and may be copied for free --providing
  22.   that it is not altered and is transferred with its documentation.
  23.   Its registration policy is as follows:
  24.  
  25.       *  The registration fee is $20 per programmer, or $50 for a site
  26.          license.  There is no run-time fee for a program compiled with
  27.          tvDMX code.
  28.  
  29.       *  tvDMX may be used only for development of compiled programs.
  30.          The source code may not be sold, except as described in the
  31.          VENDOR.DOC file.
  32.  
  33.       *  Previously registered programmers do not need to re-register
  34.          to use this version.
  35.  
  36.       *  Registered users will receive a diskette with the most recent
  37.          version of tvDMX with additional units and programs.
  38.  
  39.   Registered users are entitled to support via mail or CompuServe.
  40.   The author may be contacted at this address:
  41.      
  42.          Randolph Beck
  43.          tvDMX Registration
  44.          P.O. Box  56-0487
  45.          Orlando, FL 32856-0487
  46.  
  47.          CompuServe:  72361,753
  48.  
  49.                                                                      Page ii
  50.  
  51.                                Table of Contents
  52.                                -----------------
  53.  
  54.  
  55.  
  56.         tvDMX OVERVIEW ............................................ 1
  57.              Keystroke Philosophy ................................. 1
  58.  
  59.         tvDMX CONCEPTS ............................................ 2
  60.              The Data-Formatting Template ......................... 2
  61.  
  62.         USING tvDMX IN YOUR PROGRAMS .............................. 3
  63.              Data Windows ......................................... 3
  64.              Automatic Assignment Constructors .................... 4
  65.              Loading tvDMX Views from a Stream .................... 4
  66.  
  67.         USING tvDMX FOR SINGLE FIELD EDITORS ...................... 5
  68.  
  69.         CREATING FORMS WITH tvDMX ................................. 6
  70.              Initialization Parameters ............................ 6
  71.              Sample Form .......................................... 7
  72.              Function EntryBox() .................................. 8
  73.  
  74.         ADVANCED FEATURES ......................................... 9
  75.              User Key Errors ...................................... 9
  76.              Hidden and Read-Only Fields .......................... 9
  77.              Swapping Field Positions ............................. 9
  78.  
  79.         REFERENCE ................................................ 10
  80.              Object Hierarchy .................................... 10
  81.              Units ............................................... 11
  82.              Data Template Codes ................................. 12
  83.  
  84.         USING TEMPLATE CODES ..................................... 13
  85.              Template Control Codes .............................. 16
  86.              Field Descriptor Functions .......................... 18
  87.  
  88.         FYI ...................................................... 19
  89.              Important Virtual Methods ........................... 19
  90.              External Database Access ............................ 20
  91.              Global Functions in Units DMXGIZMA and tvGIZMA ...... 21
  92.  
  93.         INVOICE .................................................. 22
  94.  
  95.  
  96.   tvDMX OVERVIEW                                                      Page 1
  97.   ==============
  98.  
  99.   This project was originally undertaken to enable programmers to quickly
  100.   design data entry screens which users could operate in a natural and
  101.   intuitive way.  Earlier designs of tvDMX could edit data in a browse
  102.   format.  The newest derivative objects work as regular data-entry forms.
  103.  
  104.   The object-oriented framework of tvDMX can be extended to access any
  105.   type of data structure (including files, Streams and Collections).
  106.  
  107.   tvDMX display formats use picture templates and grant the programmer
  108.   full control over the appearance of each field.
  109.  
  110.   Features:
  111.       *  programmable display formats for the major Pascal data types
  112.       *  containment within a scrolling Turbo Vision view
  113.       *  record structure and display format can be set at run-time
  114.       *  hidden and read-only fields
  115.       *  field display position order can differ from physical order
  116.       *  reports can be generated for the data in views
  117.       *  support for browse and vertical record display formats
  118.  
  119.   This document should give a quick introduction to tvDMX.  Rather than
  120.   detail the inner workings, you may prefer to review several of the
  121.   instructive samples:
  122.  
  123.       SAMPLES.PAS displays several windows:  Each has data in various
  124.            formats.  This will give you an idea of what tvDMX can do.
  125.  
  126.       FORMSHOP.PAS demonstrates create form-style data entry windows.
  127.  
  128.       WORKSHOP.PAS is intended for your own experiments.  It uses the
  129.            simplest type of data window.
  130.  
  131.       FILESHOP.PAS manages data on disk via a TDosStream object --to show
  132.            that tvDMX operations are not limited to data in RAM.
  133.  
  134.       FILEDEMO.PAS also manages data on disk, but it has been customized
  135.            to use a standard Pascal file.
  136.  
  137.       COLLECTR.PAS demonstrates how to edit data in a collection.
  138.  
  139.   The source code for each of these programs contains additional
  140.   information about its use and features.
  141.  
  142.  
  143.                             Keystroke Philosophy
  144.                             --------------------
  145.  
  146.   Most keys work as you would expect.  In addition:  kbCtrlT deletes the
  147.   current field, and kbCtrlY deletes the current record.
  148.  
  149.   The kbLeft and kbRight keys normally move the field pointer from one
  150.   field to another.  Movement within a character field is permitted:
  151.  
  152.       1) After a character is entered into the field;
  153.       2) after kbIns, kbCtrlT or kbCtrlY is pressed; or
  154.       3) anytime the keyboard is not in INSERT mode.
  155.  
  156.   tvDMX CONCEPTS                                                      Page 2
  157.   ==============
  158.  
  159.                         The Data-Formatting Template
  160.                         ----------------------------
  161.  
  162.   The default appearance of these views is usually column/row oriented,
  163.   with the exception of form-like views and single fields.  You declare a
  164.   record structure for the DMX initialization procedure in a template
  165.   string --which also determines the display format.  (You will see later
  166.   how tvDMX can be used to work with forms or field editors.)
  167.  
  168.   A RECORD of STRING [20], INTEGER, and REAL may use this format:
  169.            ' ssssssssssssssssssss | iiii |($rrr,rrr.rr)'
  170.  
  171.   And that would present a records in this way:
  172.            │ Ace Exchange Network │  154 │ $ 12,056.55 │
  173.            │ CommCheck, Inc.      │  -28 │($    725.00)│
  174.  
  175.   The template string in this example was entirely in lower case.  If in
  176.   upper case, character-fields would be entered in upper case and
  177.   numeric-fields would be restricted to positive values.
  178.  
  179.   The data TYPE of each field is determined by the characters in the
  180.   string.  All primary Pascal data types are supported:  BOOLEAN, BYTE,
  181.   SHORTINT, INTEGER, LONGINT, WORD, STRING, CHAR, arrays of CHAR, and
  182.   REAL.  The programmer only needs to alter this one template string when
  183.   changing the data structure.  (Template codes are listed on the
  184.   Reference page.)
  185.  
  186.   You can switch to SINGLE, DOUBLE or EXTENDED reals by changing TYPE
  187.   TREALNUM in RSET.PAS.
  188.  
  189.  
  190.   A backslash ('\') may be used as a field delimiter, and is displayed as
  191.   a space character.  (Other delimiters can be devised as well --please
  192.   refer to the ^D control code.)
  193.  
  194.   The tilde ('~') character can be used to switch format-processing on and
  195.   off.  This makes it possible to separate the text-literals from format
  196.   and control codes:
  197.  
  198.       ' ~Name:~ ssssssssssssssssssss\ ~SSN:~ ###-##-#### '
  199.  
  200.   This is diplayed as:
  201.       ' Name: Abigail Adams         SSN: 012-34-5678 '
  202.  
  203.   String fields can now be abbreviated with the '`' character (the
  204.   backward apostrophe) so that long strings don't take so much space on
  205.   the screen.  While editing, users can scroll within the field.
  206.  
  207.   Example:
  208.       ' ssssssssssssssssssss`ssssssssssssssssssss| ww,www '
  209.  
  210.   This will be displayed like this:
  211.       ' International Busin>|  1,024 '
  212.  
  213.   The '>' would actually be an arrow character.
  214.  
  215.   USING tvDMX IN YOUR PROGRAMS                                        Page 3
  216.   ============================
  217.  
  218.                                 Data Windows
  219.                                 ------------
  220.  
  221.   Presumably you understand that a focused TScroller is owned by, and
  222.   operates within, an active TWindow.  The TScroller also has several
  223.   peer-views:  a TFrame and two TScrollBars.  If you wished, you could add
  224.   more views to display additional information.  This is how the
  225.   TDmxScroller object works, as well as its descendant TDmxEditor.  (A
  226.   TDmxScroller object displays data in a scrolling window.  TDmxEditor
  227.   --its first descendant-- adds the ability to edit the data.)
  228.  
  229.   Programmers can instantiate a TWindow view and insert a TDmxEditor
  230.   object just like using TScroller --with a few extra parameters. Then,
  231.   for an effective data window, field titles should be placed at the top,
  232.   and a record number indicator should be placed below.*
  233.  
  234.   The TDmxWindow object (a descendant of TWindow and tvGIZMA's TLtdWindow)
  235.   coordinates the entire process of inserting these extra views.
  236.  
  237.   Initialization Syntax:
  238.  
  239.       constructor TDmxWindow.Init(
  240.             var Bounds    : TRect;
  241.                 ATitle    : TTitleStr;
  242.                 ANumber   : Integer;
  243.                 ATemplate : String;
  244.             var AData;
  245.                 BSize     : Longint;
  246.             var ALabels   : String;
  247.                 IndLen    : Integer);
  248.  
  249.         Bounds, ATitle and ANumber are the same parameters required for
  250.            any TWindow object.
  251.  
  252.         ATemplate is a tvDMX data format template string.
  253.         AData refers to the data to be edited.  Note that your data is not
  254.            part of this object.
  255.         BSize is the size of the entire data structure.
  256.         ALabels is the string which labels the fields over the editor.
  257.         IndLen is the length of a record number indicator view (usually
  258.            about five to ten characters).  The default indicator is placed
  259.            just to the left of the horizontal scroll bar.
  260.  
  261.  
  262.   The TDmxWindow.Init() constructor will first assign and construct two
  263.   auxiliary views, TDmxLabels and TDmxRecInd, which serve as a field title
  264.   display and a record number indicator.  This process is managed by
  265.   virtual methods in object TDmxWindow which may be overridden with new
  266.   descendants.
  267.  
  268.  
  269.   *See WORKSHOP.PAS for an example of how to use tvDMX with TWindow types.
  270.  
  271.                      Automatic Assignment Constructors                Page 4
  272.                      ---------------------------------
  273.  
  274.   Programmers who make extensive use of tvDMX descendants may which to
  275.   avoid using TDmxWindow objects and insert TDmxEditor views directly into
  276.   TWindow or TDialog window types.  Automatic assignment constructors were
  277.   developed to make this process easier.  TDmxLabels and TDmxRecInd object
  278.   types can use alternate constructors:
  279.  
  280.       constructor TDmxLabels.InitInsert(AOwner: PGroup; var ALabels );
  281.           ALabels refers to the String that displays field heading labels.
  282.  
  283.       constructor TDmxRecInd.InitInsert(AOwner: PGroup; Len: integer);
  284.           Len refers to the desired width of the indicator view.
  285.  
  286.   Both require a pointer to the window that it will be inserted into.
  287.   They can use the size of that view to assign and position themselves.
  288.   The view insertion is also automatic.
  289.  
  290.   WORKSHOP.PAS uses automatic insertion constructors with a regular
  291.   TWindow object.
  292.  
  293.  
  294.                      Loading tvDMX Views from a Stream
  295.                      ---------------------------------
  296.  
  297.   tvDMX objects have Load() constructors and Store() destructors that load
  298.   and store the object's fields.  But it would be impractical for the
  299.   tvDMX object to also retain the window's database because the data
  300.   source can vary, depending upon the application.  Therefore, two virtual
  301.   methods should be overridden for storage on streams:
  302.  
  303.            procedure LoadData(var S: TStream);  VIRTUAL;
  304.            procedure StoreData(var S: TStream);  VIRTUAL;
  305.  
  306.   LoadData() must set Pointer WorkingData with the address of the database
  307.   and set Longint DataBlockSize with the size of the database (in bytes,
  308.   not records).  It should be designed in a way that allows for the
  309.   possibility that the database may have been removed or altered by
  310.   another program since the time this object was stored.
  311.  
  312.   StoreData() must save the database parameters in a way that it may be
  313.   reopened by LoadData().
  314.  
  315.   Note:  The LoadData() and StoreData() methods for object TInputFields
  316.   are already implemented, since their small amount of data are easily
  317.   streamed.
  318.  
  319.   USING tvDMX FOR SINGLE FIELD EDITORS                                Page 5
  320.   ====================================
  321.  
  322.   It is only natural that a descendant of TDmxEditor would be written to
  323.   serve as a replacement for the TInputLine object.
  324.  
  325.   Object TInputFields is a TDmxEditor derivative that:  1) Allocates
  326.   memory to hold the data fields;  2) Overrides the DataSize(), GetData()
  327.   and SetData() methods;  3) Uses a different palette suitable for Dialog
  328.   boxes;  and 4) Has special handling of the cursor keys to operate more
  329.   naturally within a Dialog box.
  330.  
  331.   A special insertion function was written to measure and initialize it
  332.   with an accompanying TLabel object:
  333.  
  334.     function InsertField(Dialog:            PDialog;
  335.                          Col,Row:           Integer;
  336.                          Fmt:               Boolean;
  337.                          ALabel,ATemplate:  String)  : PView;
  338.  
  339.         Dialog is a pointer to the dialog window into which these views
  340.            are inserted.
  341.         Col and Row are the upper left corner of the label.
  342.         Fmt orientation of the tvDMX editor view, relative to the
  343.            label:  If TRUE, then the editor view is below the
  344.            label;  but if FALSE, the editor view follows the label
  345.            on same line.
  346.         ALabel is the string that will become the label.
  347.         ATemplate is the string that becomes the editor view.
  348.  
  349.   This function returns a pointer to the TInputFields view.  Usually, the
  350.   pointer will be discarded (this unit is compiled with extended syntax so
  351.   that the function can be implemented as a procedure), but there will be
  352.   occasions when the pointer is needed.
  353.  
  354.     Examples:
  355.  
  356.       InsertField(Dialog, 5,2, TRUE,
  357.            '~N~ame', 'SSSSSSSSSSSSSSSSSSSS');
  358.  
  359.       InsertField(Dialog, 5,5, FALSE,
  360.            '~S~SN: ',  '###-##-####')^.HelpCtx := hcSSN;
  361.  
  362.       P := InsertField(Dialog, 5,6, FALSE,  '', '$rrr,rrr.rr ');
  363.             { note that the label is optional }
  364.  
  365.  
  366.   The "Accounts" dialog in SAMPLES.PAS demonstrates the use and operation
  367.   of the InsertField() function.
  368.  
  369.   See the next page for information on how to use tvDMX for entire forms.
  370.  
  371.   CREATING FORMS WITH tvDMX                                           Page 6
  372.   =========================
  373.  
  374.   tvDMX views are not restricted to rows and columns.  The views in unit
  375.   DMXFORMS edit data like a form.  Forms can be created by chaining TSItem
  376.   strings, and the leading PSItem pointer (which represents the top line)
  377.   is passed to the new tvDMX object's constructor.
  378.  
  379.   There are actually two new object types:  TDmxForm and its descendant
  380.   TDmxDlgForm (which is used in dialog boxes).  This is the syntax for the
  381.   two constructors:
  382.  
  383.       TDmxForm.Init(ATemplates: PSItem;
  384.                 AInScroll: boolean;
  385.                 var AData;
  386.                 var Bounds: TRect;
  387.                 ALabels,ARecInd: PDmxLink;
  388.                 AHScrollBar,AVScrollBar: PScrollBar);
  389.  
  390.       TDmxDlgForm.Init(ATemplates: PSItem;
  391.                 var Bounds: TRect;
  392.                 AHScrollBar,AVScrollBar: PScrollBar);
  393.  
  394.   Object TDmxDlgForm overrides the GetPalette() method with a palette more
  395.   suitable for a dialog box.
  396.  
  397.  
  398.                          Initialization Parameters
  399.                          -------------------------
  400.  
  401.   ATemplates is a chain of TSItem strings.  You can see how that works in
  402.       the demo code in program FORMSHOP.PAS.
  403.  
  404.   AInScroll denotes that if FALSE, the left and right cursor keys behave
  405.       as Ctrl-Left and Ctrl-Right keys when in <Ins> mode.  This defaults
  406.       to TRUE in TDmxDlgForm, so that parameter is not needed there.
  407.  
  408.   AData is the data.  Object TDmxDlgForm doesn't need this parameter
  409.       either because its data is stored locally within the object.  It is
  410.       assumed that you'd be using SetData() and GetData() in a dialog box.
  411.  
  412.   Bounds is the rectangle.  Notice that these objects don't need the
  413.       data-size because that will be inferred from the template
  414.       strings.
  415.  
  416.   ALabels and ARecInd parameters are also not in the TDmxDlgForm object.
  417.       They may be used in the same way as with object TDmxEditor.
  418.  
  419.                                 Sample Form                           Page 7
  420.                                 -----------
  421.  
  422.   Type
  423.     TMyRecordType  =  RECORD
  424.         Name     :  string[30];
  425.         SSN      :  string[9];
  426.         Balance  :  real;
  427.         Pt       :  pointer;
  428.         Value    :  real;
  429.     end;
  430.  
  431.   procedure EditForm(var AData);
  432.   var  R  : TRect;
  433.        W  : PWindow;
  434.        Templates : PSItem;
  435.   begin
  436.     Templates :=
  437.         NewSItem('~    Name~',
  438.         NewSItem( '   \ssssssssssssssssssssssssssssss',
  439.         NewSItem('',
  440.         NewSItem('~    SSN:    ~\###-##-####',
  441.         NewSItem('~    Balance:~\($rrr,rrr.zz)',
  442.         NewSItem('',
  443.         NewSItem('~    Pointer:~\HHHH:HHHH',
  444.         NewSItem('~    Value:  ~\RRR,RRR.ZZRR ~pts~',
  445.           nil)))));
  446.     R.Assign(0,0, 40,14);
  447.     New(W, Init(R, 'Small Form', wnNextAvail));
  448.     With W^ do
  449.       begin
  450.       Options := Options or ofTileable;
  451.       GetExtent(R);   { create new rectangle for editor object }
  452.       R.Grow(-1,-1);          { shrink -1 to avoid borders }
  453.       Insert(New(PDmxForm,
  454.          Init(Templates,           { template list }
  455.           MyData,           { data in form }
  456.           R,                { view's rectangle }
  457.           nil,nil,   { no DmxLabels or DmxRecInd views }
  458.           StandardScrollBar (sbHorizontal)
  459.           StandardScrollBar (sbVertical)
  460.           )
  461.       ));
  462.       end;
  463.     DisposeSItems(Templates); { Templates not needed after Init() }
  464.     DeskTop^.Insert(W);
  465.   end;
  466.  
  467.   As with the regular tvDMX templates, tilde symbols ('~') mark off
  468.   string-literals;  backslashes ('\') separate the fields;  and everything
  469.   else defines the field.  Naturally, you need to be careful about marking
  470.   these properly but it's fairly easy, and most mistakes can be found
  471.   during the first test.
  472.  
  473.   Note:  The compiler may balk at more than 20 rows of nested NewSItem()
  474.          calls, but you can combine smaller sections of a form into
  475.          individual functions.  This is demonstrated in FORMSHOP.PAS.
  476.          With scrollbars and proper segmentation, you can create huge
  477.          scrollable forms.
  478.  
  479.                             Function EntryBox()                       Page 8
  480.                             -------------------
  481.  
  482.   The TDmxDlgForm object (derived from TDmxForm) can be used in dialog
  483.   boxes.  But simple dialog boxes can easily be created using tvDMX's new
  484.   EntryBox() function.
  485.  
  486.       function EntryBox(Title       : string;
  487.                         AData       : pointer;
  488.                         AOptions    : word;
  489.                         AForm       : PSItem)  :  word;
  490.  
  491.          Title is used as the title of the dialog box.
  492.  
  493.          AData is a pointer to the data to be edited.  EntryBox creates
  494.            its own temporary data buffer, used during the editing process,
  495.            and does not transfer the data back if a cmCancel command is
  496.            generated.  You may use NIL to test the dialog box if you have
  497.            no data yet.
  498.  
  499.          AOptions uses mfXXXX codes like those from TV's standard
  500.            MessageBox() function.  It then and adds corresponding buttons
  501.            to the dialog box.  There are also three new mfXXXX codes:
  502.  
  503.                 mfHelpButton  --adds a help button to the dialog box;
  504.                 mfViewOnly    --prevents the user from editing the data;
  505.                 mfDefault     --makes the OK button the default selection.
  506.  
  507.          AForm is a PSItem pointer to the first row in the template chain.
  508.  
  509.  
  510.   Example:
  511.  
  512.       procedure EditEmployeeRecord(RecNum: longint);
  513.       var  Control  : word;
  514.            EmpRec   : EmployeeRecordType;
  515.       begin
  516.         GetRecord(EmpRec, RecNum);
  517.         Control := EntryBox('Employee', @EmpRec, mfOKCancel + mfDefault,
  518.                           NewSItem('',
  519.                           NewSItem('~    Name~',
  520.                           NewSItem( '   \ssssssssssssssssssss\   ',
  521.                           NewSItem('',
  522.                           NewSItem('~    ID Number:~\ ZZZW ',
  523.                           NewSItem('',
  524.                           NewSItem('~    Earnings:~\($rrr,rrr.zz)',
  525.                           NewSItem('',
  526.                                    nil))))))))
  527.                           );
  528.         If (Control = cmOK) then UpdateRecord(EmpRec, RecNum);
  529.       end;
  530.  
  531.  
  532.   The dialog box is automatically sized and centered.  Horizontal and
  533.   vertical scrollbars are added only if necessary.
  534.  
  535.   Remember to split large forms (20 or more rows of NewSItem calls) into
  536.   smaller sections as demonstrated by the large forms in FORMSHOP.PAS.
  537.  
  538.   ADVANCED FEATURES                                                   Page 9
  539.   =================
  540.  
  541.                               User Key Errors
  542.                               ---------------
  543.  
  544.   Keys pressed that are out of range (eg: 'z' within numeric fields) will
  545.   generate cmDMX_WrongKey command events.  See tvGIZMA.PAS for examples.
  546.  
  547.  
  548.                         Hidden and Read-Only Fields
  549.                         ---------------------------
  550.  
  551.   Some programs use data with hidden fields.  (dBASE files require a
  552.   leading byte at the beginning of each record.)  And many programs use
  553.   fields which can be seen but not altered.  (This may be when the field
  554.   is accessed by the program and not by the user.)
  555.  
  556.   Both of these situations are handled by control codes in the template
  557.   string that mark fields as Hidden or Read-Only.
  558.  
  559.   Example: ^H + 'B' + #0 + ^R + ' iii |'...
  560.  
  561.            ^H + 'B' specifies a hidden BYTE field;
  562.            #0 marks a new field without a visible delimiter;
  563.            ^R marks the next field as a Read-Only integer;  and so on...
  564.  
  565.   Program users will recognize Read-Only fields because they have their
  566.   own color in the palette (when focused).
  567.  
  568.  
  569.                           Swapping Field Positions
  570.                           ------------------------
  571.  
  572.   Date fields are often arranged in Year-Month-Day order, but the
  573.   conventional display format is Month-Day-Year.  The ^P control code
  574.   makes it possible to display and edit fields in a different order than
  575.   in which they are physically organized.  This exchange is transparent to
  576.   the user.
  577.  
  578.   Unit DMXGIZMA contains fldDATE, a string constant that uses the ^P code
  579.   to display and edit a three-word date field.  Here is how it works:
  580.  
  581.     CONST  fldDATE    =  ' WW-'^F^Z + ^U+char(12) + ^P+char(2) +
  582.                         #0'ZW-'^Z  + ^U+char(31) +
  583.                         #0'ZZZW '^Z^F + ^P+char(-6) +
  584.                         #0 + ^P+char(4);
  585.  
  586.   fldDATE defines what is called a "complex field".  The ^F control code
  587.   ensures that these three integer fields receive the same field number.
  588.   The ^P code uses the next character to adjust the data pointer forward 2
  589.   bytes, backward 6 bytes, and then 4 bytes forward again.  This way, the
  590.   YEAR-MONTH-DAY field can be displayed and edited in MONTH-DAY-YEAR
  591.   order, like this:  '  1-01-1992 '.  The ^U code is used to denote an
  592.   upper limit for each field.  Refer to the section on control codes
  593.   elsewhere in the documentation.
  594.  
  595.   These advanced features are demonstrated in program SAMPLES.PAS.
  596.  
  597.   REFERENCE                                                          Page 10
  598.   =========
  599.  
  600.                               Object Hierarchy
  601.                               ----------------
  602.  
  603.  
  604.         TObject (OBJECTS.TPU)
  605.            |
  606.         TView (VIEWS.TPU)
  607.            |
  608.         TScroller (TVIEWS.TPU)
  609.            |
  610.            |
  611.         TDmxScroller (TVDMX.PAS)
  612.            |  |
  613.            |  +--TDmxCollectView (TVDMXCOL.PAS)
  614.            |
  615.            |
  616.         TDmxEditor (TVDMX.PAS)
  617.            |
  618.            |
  619.            |--TDmxCollector (TVDMXCOL.PAS)
  620.            |
  621.            |
  622.            |--TDmxEditBuf (TVDMXBUF.PAS)
  623.            |     |
  624.            |     +--TDmxStreamBuf
  625.            |     |     |
  626.            |     |     +--TDmxExpBuf
  627.            |     |
  628.            |     +--TDmxPxEditor        // registered version only
  629.            |           |
  630.            |           +--TDmxParadox   // registered version only
  631.            |
  632.            |
  633.            |--TDmxEditDlg (STDDMX.PAS)
  634.            |     |
  635.            |     +--TInputFields
  636.            |
  637.            |
  638.            +--TDmxForm (DMXFORMS.PAS)
  639.                  |
  640.                  +--TDmxDlgForm
  641.  
  642.                                    Units                             Page 11
  643.                                    -----
  644.  
  645.       Unit RSET contains untyped constants and data types.  No objects,
  646.            procedures, functions, or typed-constants are included.
  647.  
  648.       Unit DMXGIZMA has a formatting function used internally by tvDMX and
  649.            defines the DMX-specific constants and types;
  650.  
  651.       Unit tvGIZMA has several objects and functions for Turbo Vision
  652.            support which includes TAppA  --an advanced application view;
  653.  
  654.       Unit tvDMX contains:
  655.  
  656.            object TDmxScroller  --a data scroller object
  657.            object TDmxEditor    --a data editor derived from TDmxScroller
  658.            object TDmxRecNum    --a view which displays the record number
  659.            objects TDmxExtLabels, TDmxLabels, TDmxFLabels and TDmxMLabels
  660.                      --views which displays text (used for field titles)
  661.  
  662.  
  663.       Unit StdDMX contains:
  664.  
  665.            object TDmxEditDlg  --TDmxEditor derivative for dialog boxes
  666.            object TInputFields --TInputLine replacement for all data types
  667.            object TDmxViewer   --TWindow descendant that initializes and
  668.                                  INSERTs a TDmxScroller object
  669.            object TDmxWindow   --TDmxViewer descendant that initializes
  670.                                  and INSERTs a TDmxEditor object
  671.  
  672.  
  673.       Unit tvDMXCOL contains:
  674.  
  675.            object TDmxCollector --TDmxEditor derivative for collections
  676.            object TDmxCollectorWin is a TDmxWindow derivative for
  677.            TDmxCollector
  678.  
  679.  
  680.       Unit tvDMXBUF contains buffered tvDMX objects:
  681.  
  682.            object TDmxEditBuf   --TDmxEditor derivative for external data
  683.            object TDmxStreamBuf --TDmxEditBuf derivative for stream data
  684.            object TDmxExpBuf    --descendant of TDmxStreamBuf that expands
  685.                                   as records are appended (see FILESHOP)
  686.            objects TDmxBufWin and TDmxExpBufWin  --TDmxWindow descendants
  687.                                 for control of the previous two objects;
  688.  
  689.  
  690.       Unit DMXFORMS contains objects to build forms:
  691.  
  692.            object TDmxForm      --main TDmxEditor forms object
  693.            object TDmxDlgForm   --TDmxForm derivative for dialog boxes
  694.            proc MakeEntryBox()  --creates a form in a dialog box
  695.            func EntryBox()      --uses MakeEntryBox to display a form
  696.  
  697.  
  698.       Unit tvDMXREP contains objects that output listings of tvDMX data.
  699.            Read file DMXUTILS.DOC for detailed information.
  700.  
  701.                             Data Template Codes                      Page 12
  702.                             -------------------
  703.  
  704.   Field codes:
  705.  
  706.            'S' --STRING field
  707.            '#' --STRING field (numbers only)
  708.            'C' --CHARacter field (can be used for CHAR arrays)
  709.            '0' --CHARacter field (numbers only)
  710.            'X' --BOOLEAN value field
  711.            'B' --BYTE field
  712.            'J' --SHORTINT field
  713.            'W' --WORD field
  714.            'I' --INTEGER field
  715.            'L' --LONGINT field
  716.            'R' --REAL number field (uses TYPE TREALNUM in RSET.PAS)
  717.            'N' --dBASE-formatted numeric CHAR field
  718.            'H' --HEXadecimal numeric entry
  719.            'K' --BIT CLUSTER field ('K'=CheckBox; 'k'=RadioButton)
  720.  
  721.  
  722.   Field code modifier:
  723.  
  724.            'Z' --zero modifier to force leading or trailing zeroes
  725.  
  726.  
  727.   Field control codes:
  728.  
  729.            ^A  --show all zero values in all fields
  730.            ^C  --use the next character as a field access code
  731.            ^D  --use the next character as a field delimiter
  732.            ^F  --start/end complex field
  733.            ^H  --hidden field
  734.            ^P  --display position modifier
  735.            ^R  --read-only field
  736.            ^S  --"skip" field (cursor will skip over it)
  737.            ^U  --set field's upperlimit (1 to 255 only)
  738.            ^V  --set field's default value
  739.            ^X  --special BOOLEAN field
  740.            ^Z  --show zeroes if this field is empty
  741.            '~' --switch string-literals on/off
  742.  
  743.  
  744.   Field delimiters:
  745.  
  746.            #0  --technical field delimiter (not displayed)
  747.            '\' --displayed as a space
  748.            '|' --displayed as a solid vertical line (#179)
  749.            #179 or #186 may also be used as delimiters
  750.  
  751.  
  752.   Template extension functions:  (in file DMXGIZMA.PAS)
  753.  
  754.            func InitAppendFields()
  755.            func InitBlobField()
  756.            func InitEnumField()
  757.            func InitTSItemFields()
  758.  
  759.   USING TEMPLATE CODES                                               Page 13
  760.   ====================
  761.  
  762.  
  763.   STRING Fields:
  764.  
  765.            's' regular STRING field
  766.            'S' STRING field (forces upper case)
  767.            '#' STRING field (numbers only)
  768.  
  769.       These codes are used for normal Turbo Pascal STRING types.  If the
  770.       '#' code is used then only spaces or numeric characters ('0'..'9')
  771.       can be entered.
  772.  
  773.       Examples: 'ssssssssssssssssssss'
  774.                 '~Name:~ SSSSSSSSSSSSSSSSSSSS'
  775.                 ' ###-##-#### '
  776.  
  777.  
  778.   CHAR Fields:
  779.  
  780.            'c' CHAR field
  781.            'C' CHAR field (forces upper case)
  782.            '0' CHAR field (numbers only)
  783.  
  784.       Editing keys will operate in the same manner as STRING fields when
  785.       the field contains more than one character.  (Use these codes for
  786.       dBASE file structures.)  If the '0' code is used then only spaces or
  787.       numeric characters ('0'..'9') can be entered.
  788.  
  789.       Examples: 'C'
  790.                 'cccccccccccccccccccc'
  791.                 '~Name:~ CCCCCCCCCCCCCCCCCCCC'
  792.                 ' 000-00-0000 '
  793.  
  794.  
  795.   BOOLEAN Fields:
  796.  
  797.            'X' regular BOOLEAN field
  798.            ^X  indicates special BOOLEAN field
  799.  
  800.       A regular BOOLEAN field will display the character ShowTRUE (as
  801.       defined in unit DMXGIZMA) or ShowFALSE, depending upon the value of
  802.       that field.  A special BOOLEAN field has no indicator of its own,
  803.       but will display the template only if the data is TRUE.
  804.  
  805.       Examples: 'X'
  806.                 '[X]'
  807.                 '~TRUE~' + ^X
  808.  
  809.                                                                      Page 14
  810.   INTEGER Fields:
  811.  
  812.            'B' BYTE field
  813.            'J' SHORTINT field
  814.            'W' WORD field
  815.            'I' INTEGER field
  816.            'L' LONGINT field
  817.            'Z' ZERO modifier to display leading zeroes
  818.  
  819.       The value of each field is limited to the natural limit of its field
  820.       TYPE, regardless of the displayed width of its template.  Upper case
  821.       codes signify that negative numbers are not permitted.  (Case is not
  822.       relevant for BYTE and WORD fields.)
  823.       The 'Z' modifier can be used to force the display of a leading zero
  824.       as long as the data type is in one of the template
  825.       characters.
  826.  
  827.       Examples: 'BBB'
  828.                 'WWWWW'
  829.                 'ZZZZW'
  830.                 'ii,iii'
  831.                 '%WZW'
  832.                 'LLL,LLL,LLL'
  833.  
  834.  
  835.   REAL Number Fields:
  836.  
  837.            'R' REAL number field
  838.  
  839.       REAL numbers are declared like other numeric fields except that
  840.       parentheses '('/')' can be used to enclose the template.  These will
  841.       be displayed only if the value is a negative number.
  842.  
  843.       Floating point numbers other than of TYPE REAL can be used if TYPE
  844.       TREALNUM is changed in RSET.PAS.  (See RSET.PAS.)
  845.  
  846.       New in version 2.0:  Trailing zeroes will not be displayed unless
  847.       'z' was used in the template.
  848.  
  849.       Examples: '($rrr,rrr.zz)'
  850.                 'rr,rrr.zrrr'
  851.                 'RRRRR.RRR'
  852.  
  853.  
  854.   Hexadecimal Fields:
  855.  
  856.            'H' Hexadecimal numeric field
  857.  
  858.       Used for displaying and editing data in hexadecimal formats.  The
  859.       size and type of the field is dependent upon the number of H's.
  860.       This code is used extensively in unit tvDMXHEX.PAS.
  861.  
  862.       Examples: 'HH'
  863.                 'HHHH'
  864.                 'HHHH:HHHH'
  865.  
  866.                                                                      Page 15
  867.   dBASE-formatted numeric CHAR Fields:
  868.  
  869.            'N' Numeric character field
  870.  
  871.       These fields are stored as character arrays but are edited like the
  872.       numeric fields.  This may be formatted like any numeric field except
  873.       that parentheses cannot be used.  dBASE date fields can be formatted
  874.       using 'Z' modifiers and a system of ^P codes.  (See fldNDATE in
  875.       FILESHOP.PAS.)
  876.  
  877.       Examples: 'nnn'
  878.                 'ZZN'
  879.                 '$nnn,nnn.zz'
  880.  
  881.  
  882.   BIT-CLUSTER Fields:
  883.  
  884.            'K' + CHAR     CheckBox bit field
  885.            'k' + CHAR     RadioButton bit field
  886.  
  887.       Cluster fields emulate Turbo Vision's TCluster views within a tvDMX
  888.       scroller.  They were originally intended for form-views, but they
  889.       can be used in any type of tvDMX object.
  890.  
  891.       The 'K' or 'k' template code is followed by another character that
  892.       designates which cluster it belongs to.  It does not matter what
  893.       this character is, as long as each cluster has its own.
  894.  
  895.       Examples: NewSItem(' [KA] ~Box 1     ~\ (kB) ~Button 1   ~',
  896.                 NewSItem(' [KA] ~Box 2     ~\ (kB) ~Button 2   ~',
  897.                 NewSItem(' [KA] ~Box 3     ~\ (kB) ~Button 3   ~',
  898.                 NewSItem(' [KA] ~Box 4     ~\ (kB) ~Button 4   ~',
  899.                      nil)))
  900.  
  901.       These examples use a cluster of checkboxes identified as bank 'A',
  902.       and a cluster of radiobuttons identified as bank 'B'  The brackets
  903.       and parentheses are not significant and may be substituted.  The 'A'
  904.       and 'B' cluster-ID's are not displayed.
  905.  
  906.       By default, each cluster-group holds one WORD-type of data.  So,
  907.       there can be up to 16 controls for each RadioButton-cluster.  This
  908.       can be changed to a LONGINT type by setting SizeOfFldCluster := 4;
  909.  
  910.                            Template Control Codes                    Page 16
  911.                            ----------------------
  912.  
  913.   Switch to Literals:
  914.  
  915.            '~'
  916.  
  917.       Switches DMX template interpretation to codes or literals.  This
  918.       permits static-text to be used in a template string.
  919.  
  920.       Examples: '~Name:~ SSSSSSSSSSSSSSSSSSSS'
  921.                 '$RR,RRR.RR ~CR~'
  922.  
  923.  
  924.   String/Character Field Contraction:
  925.  
  926.            '`'
  927.  
  928.       Shortens the visible portion of a string field.  Only the portion of
  929.       the template before the '`' marker will be displayed.  The remainder
  930.       can be seen and edited by scrolling (within the field) to the
  931.       right.
  932.  
  933.       Examples: '~Name:~ SSSSSSSSSSSSSSSSSSSS`SSSSSSSSSSSSSSS'
  934.                 ' cccccccccc`cccccccccccccccccccc'
  935.  
  936.  
  937.   Special Field Attributes:
  938.  
  939.            ^A  show zeroes in all fields
  940.            ^C' use the next character as a field access code
  941.            ^H  Hidden field
  942.            ^R  Read-Only field
  943.            ^S  Skip field (cursor will skip over it)
  944.            ^Z  show zeroes if this field is empty
  945.  
  946.       Every field has its own field-access attribute. They may be combined
  947.       as needed.  ^A will function as though was set ^Z for each field.
  948.       ^C+char(accSpecA) sets the accSpecA flag for that field.  (accSpecA,
  949.       accSpecB and accSpecC flags are available for your own custom use.)
  950.       Note that Hidden or Skip fields can still be zeroized when the
  951.       record is zeroized, unless it is also marked as Read-Only.
  952.  
  953.  
  954.   Define Template Delimiter:
  955.  
  956.            ^D + CHAR
  957.  
  958.       Uses the following character as a field delimiter.
  959.  
  960.       Examples: ' WW' + ^D+'-WW' + ^D'-WWWW '
  961.                 ^D + #255
  962.  
  963.                                                                      Page 17
  964.   Start/End Complex Field:
  965.  
  966.            ^F
  967.  
  968.       Begins or ends a complex field.  Each individual field within a
  969.       complex field group is given the same field number.
  970.  
  971.       Example:  ^F + ' BB | BB | WWWW ' + ^F
  972.  
  973.  
  974.   Position Modifier:
  975.  
  976.            ^P + CHAR
  977.  
  978.       Sets the position within the record (and also the record size) to
  979.       another point relative to the number of bytes indicated by the
  980.       SHORTINT value of the following character.  This is used by the
  981.       fldDATE constant to swap the diplay positions of a date record from
  982.       Year-Month-Day to Month-Day-Year.
  983.  
  984.       Examples: ^P + char(20)
  985.                 ^P + char(-4)
  986.  
  987.  
  988.   Set Field Upper Limit:
  989.  
  990.            ^U + CHAR
  991.  
  992.       The next character will be the field's upper limit (up to 255).
  993.       This is used by fldDATE to limit months to 12 and days to 31.
  994.  
  995.       Example:  ^U + char(12)
  996.  
  997.  
  998.   Set Field Default Value:
  999.  
  1000.            ^V + CHAR
  1001.  
  1002.       The following character will be the field's default value, which is
  1003.       set when it is zeroized.  Normally this would be zero for numerics
  1004.       and spaces for character fields.
  1005.  
  1006.       Example:  ^V + '0'
  1007.  
  1008.                          Field Descriptor Functions                  Page 18
  1009.                          --------------------------
  1010.  
  1011.   Some situations require special functions that assign control codes.
  1012.   The following functions return DmxIDstr strings (which are STRING[8]
  1013.   types) that have the required control codes.
  1014.  
  1015.  
  1016.       function  InitAppendFields(ATemplate: pstring) : DmxIDstr;
  1017.  
  1018.            Initializes a pointer to more field templates.  This can
  1019.            be used to increase the effective length of your template.
  1020.            You can also use function InitTSItemFields() to extend
  1021.            template strings.
  1022.  
  1023.            Example:  Stx2 := 'WW,WWW |WW,WWW | CCCCCCCC ';
  1024.                      Stx1 := ' sssssssssssssss|WW,WWW |'
  1025.                              + InitAppendFields (@Stx2);
  1026.  
  1027.  
  1028.       function  InitBlobField(Len: integer;
  1029.                               AccMode,Default: byte) : DmxIDstr;
  1030.  
  1031.            Initializes an unformatted data field of the given field
  1032.            length.  BLOb fields take space within the record but will
  1033.            not be displayed.  Use procedure GetBlob() in unit
  1034.            STDDMX.PAS to retrieve this data.
  1035.  
  1036.            Example:  Stx := ' sssssssssssssss|WW,WWW | CCCCCCCC ' +
  1037.                                InitBlobField (20, AccNormal, 0);
  1038.  
  1039.  
  1040.       function  InitEnumField(ShowZ: boolean; AccMode,Default: byte;
  1041.            AItems: PSItem) : DmxIDstr;
  1042.  
  1043.            Initializes a tvDMX enumerated field list.
  1044.  
  1045.            Example:
  1046.               Stx := ' sssssssssssssss|WW,WWW |'
  1047.                   +  InitEnumField (FALSE, AccNormal, 0,
  1048.                                     NewSItem (' Zero ',
  1049.                                     NewSItem (' One',
  1050.                                     NewSItem (' Two', nil))))
  1051.                   + '| ###-#### |rrr,rrr.rrr ';
  1052.  
  1053.  
  1054.       function  InitTSItemFields (ATemplates : PSItem) : DmxIDstr;
  1055.  
  1056.            Initializes a chain of TSItem templates.  This can be used
  1057.            to increase the effective length of your template.
  1058.  
  1059.            Example:
  1060.               Stx := ' sssssssssssssss|WW,WWW |' +
  1061.                      InitTSItemFields(NewSItem(' ssssssssssssss|',
  1062.                                       NewSItem('($rrr,rrr.rr)|',
  1063.                                       NewSItem(' CCCCC|WWW,WWW ',
  1064.                                                nil))))
  1065.  
  1066.   FYI                                                                Page 19
  1067.   ===
  1068.                          Important Virtual Methods
  1069.                          -------------------------
  1070.  
  1071.   The following is a short list of some of the virtual methods that may be
  1072.   overridden or intercepted in descendant objects.
  1073.  
  1074.  
  1075.   Function  TDmxEditor.DataAt(RecNum: integer) : pointer;  VIRTUAL;
  1076.  
  1077.       Returns a pointer to the given data record.  By overriding this
  1078.       function, a program can alter the manner in which the database
  1079.       is organized.  This method is used exclusively for data
  1080.       retrieval --which allows programs to access over 64k.
  1081.  
  1082.       The objects in unit tvDMXBUF.PAS override this method to
  1083.       retrieve data records from external sources, but they use a
  1084.       buffer to store enough data to reduce delay from disk access
  1085.       while scrolling.
  1086.  
  1087.       The default method simply returns a pointer to the position in
  1088.       the database from (RecNum * RecordSize).
  1089.  
  1090.  
  1091.   Procedure TDmxEditor.EvaluateField;  VIRTUAL;
  1092.  
  1093.       Called AFTER each FIELD is edited.  It adjusts internal fields
  1094.       and calls DrawField() to redraw the field in the regular color.
  1095.       Programmers who wish to override this method should call its
  1096.       ancestor in the descendant object.
  1097.  
  1098.  
  1099.   Procedure TDmxEditor.EvaluateRecord;  VIRTUAL;
  1100.  
  1101.       Called AFTER each RECORD is edited.  The objects in unit
  1102.       tvDMXBUF override this method to return the data record to
  1103.       storage.  Programmers who wish to override this method should
  1104.       call its ancestor in the descendant object.
  1105.  
  1106.  
  1107.   Procedure TDmxEditor.SetUpField;  VIRTUAL;
  1108.  
  1109.       Called BEFORE each FIELD is edited.  May call
  1110.       RecInd^.DrawView() if a record number indicator view is linked.
  1111.       Programmers who wish to override this method should call its
  1112.       ancestor in the descendant object.
  1113.  
  1114.  
  1115.   Procedure TDmxEditor.SetUpRecord;  VIRTUAL;
  1116.  
  1117.       Called BEFORE each RECORD is edited.  This can be intercepted
  1118.       to display special information (eg: record number) or to
  1119.       rearrange the record before editing.  Programmers who wish to
  1120.       override this method should call its ancestor in the descendant
  1121.       object.
  1122.  
  1123.                           External Database Access                   Page 20
  1124.                           ------------------------
  1125.  
  1126.   TDmxEditBuf is a descendant of TDmxEditor that uses a circular buffer to
  1127.   edit data from a source other than in RAM.  This can be overridden to
  1128.   access your own database library procedures, although this will not be
  1129.   an easy project.
  1130.  
  1131.   It retrieves each record individually when accessed.  The buffer is used
  1132.   only for quick page draws.
  1133.  
  1134.   This object can be found in unit tvDMXBUF.  It uses several abstract
  1135.   methods and must not be instantiated as is.  Objects TDmxStreamBuf,
  1136.   TDmxExpBuf and TDmxPxEditor are usable descendants.  Object TDmxExpBuf
  1137.   is demonstrated in program FILESHOP.PAS.  (Object TDmxPxEditor is part
  1138.   of the PxDMX.PAS unit, which is issued separately.)
  1139.  
  1140.   Descendants MUST override SeekRec(), SeekEnd, ReadRec() and WriteRec():
  1141.  
  1142.  
  1143.       Function  TDmxEditBuf.SeekRec(RecNum: integer) : boolean;  VIRTUAL;
  1144.  
  1145.            This abstract virtual method is called before reading or
  1146.            writing a record.  It must seek to the given record position.
  1147.            It is important that you remember that the first record is
  1148.            numbered 0.  It should seek to RecNum+1 if the database is
  1149.            structured with record number 1 as the first record.
  1150.  
  1151.  
  1152.       Function  TDmxEditBuf.SeekEnd : boolean;  VIRTUAL;
  1153.  
  1154.            This abstract virtual method must seek to the end of the
  1155.            database (after the last record).  Since this seeks to a
  1156.            record that does not exist, most databases will only
  1157.            require that SeekEnd return TRUE.
  1158.  
  1159.  
  1160.       Function  TDmxEditBuf.ReadRec(var RecData ) : boolean;  VIRTUAL;
  1161.  
  1162.            Abstract virtual method called to retrieve record RecData.
  1163.            It must return a record exactly the size determined by the
  1164.            template.
  1165.  
  1166.  
  1167.       Function  TDmxEditBuf.WriteRec(var RecData ) : boolean;  VIRTUAL;
  1168.  
  1169.            Abstract virtual method called by EvaluateRecord() to
  1170.            store record RecData if a change was made.
  1171.  
  1172.  
  1173.   These functions must perform their record operations at the current
  1174.   record position and return TRUE if the operation succeeded or FALSE if
  1175.   it failed.  It is the programmer's responsibility to retain the error
  1176.   code for use by the ErrorFunc() method.
  1177.  
  1178.   TDmxEditBuf.ErrorFunc() is a virtual method that may be overridden for
  1179.   special handling of database errors.
  1180.  
  1181.   Please refer to file tvDMXBUF for more information.
  1182.  
  1183.                Global Functions in Units DMXGIZMA and tvGIZMA        Page 21
  1184.                ----------------------------------------------
  1185.  
  1186.  
  1187.       Procedure AssignWinRect(var Bounds: TRect; MaxX, MaxY: integer);
  1188.  
  1189.            Assigns Bounds to fit into the desktop, with MaxX and MaxY as
  1190.            the maximum desired width and height.  Bounds is cut and moved
  1191.            to a cascaded position behind the currently active window.
  1192.            (This is similar to what happens when a new file is loaded into
  1193.            the TP IDE.)
  1194.          * Turbo Pascal 7.0 and above uses the Application^.GetTileRect()
  1195.            method to determine the default window bounds.
  1196.  
  1197.  
  1198.       Function  DmxStrLen(S: string)  : integer;
  1199.  
  1200.            Returns the length of the visible portions of a template
  1201.            string.  (From unit DMXGIZMA)  Not for use with forms.
  1202.  
  1203.  
  1204.       Function  wnNextAvail : integer;
  1205.  
  1206.            Returns the next available (unused) window number.  This was
  1207.            formerly called NextWindowNumber().
  1208.  
  1209.  
  1210.       Procedure TrimDialog(Window: PWindow);
  1211.  
  1212.            Shrinks and centers a dialog window to ease the design process.
  1213.            The dialog window should be initialized with the maximum size
  1214.            allowable.  TrimDialog() can be called after the controls are
  1215.            inserted to resize the window down to the maximum size needed.
  1216.            See program DLGSHOP.PAS for sample usage.
  1217.  
  1218.  
  1219.       TAppA          =  OBJECT(TApplication)
  1220.  
  1221.            TApplication extension that initializes TV's major components
  1222.            after saving the original user screen.  Buttons and other
  1223.            dialog box controls in applications using TAppA will respond to
  1224.            UP, DOWN, RIGHT and LEFT cursor keys.  It provides for handling
  1225.            of the cmBeep cmDMX_WrongKey, cmUserScreen, cmToggleSound,
  1226.            cmToggleVideo, cmCascade and cmTile command events.
  1227.          * Although the demo programs use derivatives of TAppA, it is not
  1228.            required for tvDMX.
  1229.  
  1230.  
  1231.       TAppPrn        =  OBJECT(TAppA)
  1232.  
  1233.            TAppPrn provides additional support for printing tvDMX windows
  1234.            (to printer or file).  See the example programs.
  1235.  
  1236.  
  1237.       TUserScreen    =  OBJECT(TScroller)
  1238.  
  1239.            Scroller object that displays the original user screen that has
  1240.            been saved by the TAppA.Init() constructor.
  1241.  
  1242.   INVOICE                                                            Page 22
  1243.   ================================================================
  1244.  
  1245.   Remit to:                          From:
  1246.  
  1247.     Randolph Beck                      _________________________
  1248.     P.O. Box  56-0487                  _________________________
  1249.     Orlando, FL 32856                  _________________________
  1250.     CIS: 72361,753                     _________________________
  1251.                                        _________________________
  1252.  
  1253.                                      Contact individual
  1254.                                        _________________________
  1255.                                        _________________________
  1256.  
  1257.  
  1258.  
  1259.              Qty                          Unit Price
  1260.  
  1261.              ___   tvDMX Registration       $ 20.00
  1262.              ___   tvDMX Site License       $ 50.00*
  1263.  
  1264.                                    Total    _______
  1265.  
  1266.  
  1267.                      *Site license includes price of registration.
  1268.  
  1269.     Note that the tvDMX toolkit has been delivered and accepted by
  1270.     the customer. A current disk, including full documentation and
  1271.     more units, will be sent upon receipt of this paid invoice.
  1272.  
  1273.  
  1274.  
  1275.     Client Information (Optional)
  1276.     ------------------
  1277.  
  1278.       How long have you been using Turbo Vision?  _________
  1279.  
  1280.       Which version of Turbo Pascal are you using?  _______
  1281.  
  1282.       List tools that you use:         Where did you find tvDMX?
  1283.        [ ] AnsiView                     ( ) BBS_________________
  1284.        [ ] Blaise:                      ( ) CompuServe
  1285.        [ ] Btrieve                      ( ) Internet
  1286.        [ ] Paradox Engine               ( ) User group
  1287.        [ ] Topaz                        ( ) friend or collegue
  1288.        [ ] Turbo Pascal for Windows     ( ) Other:
  1289.        [ ] TurboPower:________________      ____________________
  1290.  
  1291.       Others: __________________________________________________
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.   ================================================================
  1300.   tvDMX 2.5
  1301.